package com.yunhe.authority.repository.authority.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yunhe.authority.domain.authority.Role;
import com.yunhe.authority.repository.authority.RoleRepository;
import com.yunhe.authority.repository.company.dao.EmployeeDao;
import com.yunhe.common.model.PageParam;
import com.yunhe.common.util.StringUtil;
import org.neo4j.ogm.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @author zhengbo
 * @date 2021/6/18 11:36
 */
@Repository
public class RoleDao {

    @Autowired
    private Session session;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private UserDao userDao;

    @Autowired
    private EmployeeDao employeeDao;

    public Page<Role> findAllRoles(String keywords,
                                   PageParam pageParam) {
        StringBuffer cql = new StringBuffer();

        //拼接基本语句
        cql.append("MATCH(r:Role) WHERE 1=1 ");
        if (!StringUtil.isEmpty(keywords)) {
            cql.append(" AND (r.name=~'.*" + keywords + ".*' ");
            cql.append(" or r.title=~'.*" + keywords + ".*') ");
        }
        //拼接返回值和Limit部分
        int skip = (pageParam.getPage() - 1) * pageParam.getSize();
        String queryEnd = " RETURN r order by r.createTime desc SKIP " + skip + " LIMIT " + pageParam.getSize();
        String countEnd = " RETURN count(r)";

        //分页数据查询结果
        Iterable<Role> roles = session.query(Role.class, cql.toString() + queryEnd, Maps.newHashMap());
        //查询总数
        Integer total = session.queryForObject(Integer.class, cql.toString() + countEnd, Maps.newHashMap());

        //封装为分页类
        List<Role> content = Lists.newArrayList(roles);
        //查询关联用户列表
        content.forEach(role -> role.setNumberOfAssociatedUsers(userDao.calculateUserByStationIdOrFirmId(role.getId(), null, null)));

        Pageable pageable = PageRequest.of(pageParam.getPage() - 1, pageParam.getSize());
        Page<Role> page = new PageImpl<Role>(content, pageable, total);
        return page;
    }

    public Page<Role> findRolesByFirmId(Long firmId,
                                        String keywords,
                                        PageParam pageParam) {

        StringBuffer cql = new StringBuffer();

        //拼接基本语句
        cql.append("match(f:Firm)-[:HAS_ROLE]->(r:Role) where ID(f)=" + firmId + " ");
        if (!StringUtil.isEmpty(keywords)) {
            cql.append(" AND (r.name=~'.*" + keywords + ".*' ");
            cql.append(" or r.title=~'.*" + keywords + ".*') ");
        }
        //拼接返回值和Limit部分
        int skip = (pageParam.getPage() - 1) * pageParam.getSize();
        String queryEnd = " RETURN r order by r.createTime desc SKIP " + skip + " LIMIT " + pageParam.getSize();
        String countEnd = " RETURN count(r)";

        //分页数据查询结果
        Iterable<Role> roles = session.query(Role.class, cql.toString() + queryEnd, Maps.newHashMap());
        //查询总数
        Integer total = session.queryForObject(Integer.class, cql.toString() + countEnd, Maps.newHashMap());

        //封装为分页类
        List<Role> content = Lists.newArrayList(roles);
        //查询关联用户列表
        content.forEach(role -> role.setNumberOfAssociatedUsers(userDao.calculateUserByStationIdOrFirmId(role.getId(), null, firmId)));

        Pageable pageable = PageRequest.of(pageParam.getPage() - 1, pageParam.getSize());
        Page<Role> page = new PageImpl<Role>(content, pageable, total);
        return page;
    }

    public Page<Role> findRolesByStationId(Long stationId,
                                           String keywords,
                                           PageParam pageParam) {

        StringBuffer cql = new StringBuffer();

        //拼接基本语句
        cql.append("match(s:Station)-[:HAS_ROLE]->(r:Role) where ID(s)=" + stationId + " ");
        if (!StringUtil.isEmpty(keywords)) {
            cql.append(" AND (r.name=~'.*" + keywords + ".*' ");
            cql.append(" or r.title=~'.*" + keywords + ".*') ");
        }
        //拼接返回值和Limit部分
        int skip = (pageParam.getPage() - 1) * pageParam.getSize();
        String queryEnd = " RETURN r order by r.createTime desc SKIP " + skip + " LIMIT " + pageParam.getSize();
        String countEnd = " RETURN count(r)";

        //分页数据查询结果
        Iterable<Role> roles = session.query(Role.class, cql.toString() + queryEnd, Maps.newHashMap());
        //查询总数
        Integer total = session.queryForObject(Integer.class, cql.toString() + countEnd, Maps.newHashMap());

        //封装为分页类
        List<Role> content = Lists.newArrayList(roles);
        //查询关联用户列表
        content.forEach(role -> role.setNumberOfAssociatedUsers(userDao.calculateUserByStationIdOrFirmId(role.getId(), stationId, null)));

        Pageable pageable = PageRequest.of(pageParam.getPage() - 1, pageParam.getSize());
        Page<Role> page = new PageImpl<Role>(content, pageable, total);
        return page;
    }


    /**
     * 根据默认单位id查询角色列表
     *
     * @param firmId 单位id
     *               这边f.id与id(f)不一样，因为一些问题所以这么写
     * @return Page
     */
    public Page<Role> findRolesByDefaultFirmId(Long firmId,
                                               String keywords,
                                               PageParam pageParam) {

        StringBuffer cql = new StringBuffer();

        //拼接基本语句
        cql.append("match(f:Firm)-[:HAS_ROLE]->(r:Role) where f.id=" + firmId + " ");
        if (!StringUtil.isEmpty(keywords)) {
            cql.append(" AND (r.name=~'.*" + keywords + ".*' ");
            cql.append(" or r.title=~'.*" + keywords + ".*') ");
        }
        //拼接返回值和Limit部分
        int skip = (pageParam.getPage() - 1) * pageParam.getSize();
        String queryEnd = " RETURN r order by r.createTime desc SKIP " + skip + " LIMIT " + pageParam.getSize();
        String countEnd = " RETURN count(r)";

        //分页数据查询结果
        Iterable<Role> roles = session.query(Role.class, cql.toString() + queryEnd, Maps.newHashMap());
        //查询总数
        Integer total = session.queryForObject(Integer.class, cql.toString() + countEnd, Maps.newHashMap());

        //封装为分页类
        List<Role> content = Lists.newArrayList(roles);
        //查询关联用户列表
        content.forEach(role -> role.setNumberOfAssociatedUsers(userDao.calculateUserByStationIdOrFirmId(role.getId(), null, null)));

        Pageable pageable = PageRequest.of(pageParam.getPage() - 1, pageParam.getSize());
        Page<Role> page = new PageImpl<Role>(content, pageable, total);
        return page;
    }

    /*********************************企业用到*****************************/
    /**
     * 根据默认单位id查询角色列表
     *
     * @param companyId 单位id
     *                  这边f.id与id(f)不一样，因为一些问题所以这么写
     * @return Page
     */
    public Page<Role> findRolesByCompanyId(Long companyId,
                                           String keywords,
                                           PageParam pageParam) {

        StringBuffer cql = new StringBuffer();

        //拼接基本语句
        cql.append("match(c:Company)-[:HAS_ROLE]->(r:Role) where id(c)=" + companyId + " ");
        if (!StringUtil.isEmpty(keywords)) {
            cql.append(" AND (r.title=~'.*" + keywords + ".*') ");
        }
        //拼接返回值和Limit部分
        int skip = (pageParam.getPage() - 1) * pageParam.getSize();
        String queryEnd = " RETURN r order by r.createTime desc SKIP " + skip + " LIMIT " + pageParam.getSize();
        String countEnd = " RETURN count(r)";

        //分页数据查询结果
        Iterable<Role> roles = session.query(Role.class, cql.toString() + queryEnd, Maps.newHashMap());
        //查询总数
        Integer total = session.queryForObject(Integer.class, cql.toString() + countEnd, Maps.newHashMap());

        //封装为分页类
        List<Role> content = Lists.newArrayList(roles);

        //查询关联用户列表
        content.forEach(role -> role.setNumberOfAssociatedUsers(employeeDao.countEmployeesByCompanyIdAndRoleId(companyId, role.getId())));

        Pageable pageable = PageRequest.of(pageParam.getPage() - 1, pageParam.getSize());
        Page<Role> page = new PageImpl<Role>(content, pageable, total);
        return page;
    }
}
